<template>
  <!--模板-->
  <h1> reactive 失去响应性的各种情况</h1>
  多层：{{ more }}<br>
  单层：{{ foo }}<br>
  myReactive：{{ foo3 }}<br>
  myReactive.$state：{{ foo3.$state }}<br>
  <el-button type="" @click="myChange">直接赋值 reactive </el-button><br>
  <el-button type="" @click="myChange2">修改 reactive 的第二层 </el-button><br>
  <el-button type="" @click="myChange3">修改 reactive 第二层的值 </el-button><br>
  <el-button type="" @click="myChange8">使用 $state </el-button><br>
  <hr>
  <el-button type="" @click="pause">暂停 </el-button><br>
  <el-button type="" @click="resume">恢复 </el-button><br>
  <el-button type="" @click="stop">停止 </el-button><br>
</template>


<script setup lang="ts" generic="T extends {name: string}">
  import { reactive, watch, toRaw } from 'vue'
  import type { Reactive } from 'vue'
  
  type TState<T extends Object> = {
    $state(obj: T): T
  }

  interface IState<T extends Object> {
    $state: (obj:T) => T
  }


  function myReactive<T extends Object>(obj: T) {
    const re = reactive(obj)
    Object.defineProperty(re, '$state', {
      get: () => { return re },
      set: (_obj: T | T[]) => {
        // 浅层赋值
        if (Array.isArray(re)) {
          // 数组
          // re.splice(0, re.length,..._obj)
          re.length = 0
          re.push(..._obj)
        } else {
          // 对象
          Object.assign(re, _obj)
        }
      }
    })
    return re as Reactive<T> & IState<T>

  }

  const foo1 = reactive ({name:'jyk'})
  const foo2 = reactive ({name:'jyk'})

  console.log('foo1 === foo2：', foo1 === foo2) // false，两个不同对象的代理，地址（指针）不同

  let foo = reactive ({name:'jyk'})
  let index = 0

  const foo3 = myReactive({name:'jyk'})

  console.log(' defineProperty 的 foo3：',foo3)
  console.log('  foo3.keys：', Object.keys(foo3))
  console.log('  foo3 的 toRaw：', toRaw(foo3))

  const myChange8 = () => {
    foo3.$state = {
      name: '$state == jyk--' + index++
    }
  }

  const myChange = () => {
    foo = reactive ({name:'jyk--' + index++}) // 不响应
    //foo = {name:'jyk999'} // 不响应
    // console.log('改变后的 foo：',foo)
  }

  const more = reactive({
    name: 'jyk',
    info: {
      name: '第二层'
    }
  })

  const myChange2 = () => {
    more.info = reactive({name:'jyk999'})
    console.log('改变第二层后的 more：', more)
  }
  
  const myChange3 = () => {
    more.info.name = (index++).toString() // 不响应
    // console.log('改变第二层 值 more：', more)
  }

  // 默认深层监听
  const runner = watch(more, () => {
    // 可以响应第二层的整体赋值
    console.log('watch more------：', more)
  })

  // 监听的是筐还是苹果？是苹果
  watch(more.info, () => {
    // 不会响应第二层的整体赋值
    // console.log('watch more.info：', more.info)

  })

  // 监听的是筐的变化，换新也能监听
  watch(() => more.info, () => {
    // 可以响应第二层的整体赋值
    //console.log('watch () => more.info：', more.info)

  })
 
   // 深层监听，筐、苹果都能监听
   watch(() => more.info, () => {
    // 可以响应第二层的整体赋值
    //console.log('深层 watch () => more.info：', more.info)
  },{deep:true})

  const stop = () => {
    runner.stop() // 停止监听，不能恢复
  }
  
  const pause = () => {
    runner.pause() // 暂停后可以恢复
  }
  
  const resume = () => {
    runner.resume()
  }

</script>